﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace XModem.library
{
   public static class RegisterSystemHelp
    {
        //public static List<String> AddrList = new List<string>() { "80500020", "80500021" ,"80500030", "80500031", "80500032", "80500033"};
        public static List<String> SysList = new List<string>() { "80500020", "80500021", "80500050", "80500051", "80500052", "80500053" };
        public static List<String> ArmList = new List<string>() { "80500030", "80500031", "80500050", "80500051", "80500052", "80500053" };

        public static string jzTemp = ConfigurationManager.AppSettings["PAD_CLK"];

        /// <summary>
        /// 获取bit1第一位值
        /// </summary>
        /// <param name="a30">16进制80500030值</param>
        /// <returns>转bit1第一位值</returns>
        public static int BypassPLLcoreConfigValue(string a30) {
            int temp = Convert.ToInt32(a30, 16);
            var BinaryTemp = Convert.ToString(temp, 2).PadLeft(8, '0').ToList();
            return int.Parse(BinaryTemp[6].ToString());
        }
        /// <summary>
        /// 获取bit567
        /// </summary>
        /// <param name="a30">16进制80500030值</param>
        /// <returns>转bit567值</returns>
        public static int VCO_pre_dividerConfigValue(string a30) {
            int temp = Convert.ToInt32(a30, 16);
            var BinaryTemp = Convert.ToString(temp, 2).PadLeft(8, '0').ToList();
            string bit567 = $"{BinaryTemp[0]}{BinaryTemp[1]}{BinaryTemp[2]}";
            return Convert.ToInt32(bit567, 2);
        }
        /// <summary>
        /// 获取bit0123456
        /// </summary>
        /// <param name="a31">16进制80500031值</param>
        /// <returns>转bit0123456值</returns>
        public static double vco_loop_dividerConfigValue(string a31) {
            int temp = Convert.ToInt32(a31, 16);
            var BinaryTemp = Convert.ToString(temp, 2).PadLeft(8, '0').ToList();
            string bit0123456 = $"{BinaryTemp[1]}{BinaryTemp[2]}{BinaryTemp[3]}{BinaryTemp[4]}{BinaryTemp[5]}{BinaryTemp[6]}{BinaryTemp[7]}";
            return  Convert.ToInt32(bit0123456, 2); //转16进制数

        }
        /// <summary>
        /// 获取bit01
        /// </summary>
        /// <param name="a32">16进制80500032值</param>
        /// <returns>转bit01</returns>
        public static int vco_loop_divfConfigValue(string a32) {
            int temp = Convert.ToInt32(a32, 16);
            var BinaryTemp = Convert.ToString(temp, 2).PadLeft(8, '0').ToList();
            string bit01 = $"{BinaryTemp[6]}{BinaryTemp[7]}";
            return Convert.ToInt32(bit01, 2);
        }
        /// <summary>
        /// 获取bit4567
        /// </summary>
        /// <param name="a32">16进制80500032值</param>
        /// <returns>转bit4567</returns>
        public static int pll_clock_divider(string a32) {

            int temp = Convert.ToInt32(a32, 16);
            var BinaryTemp = Convert.ToString(temp, 2).PadLeft(8, '0').ToList();
            string bit0123 = $"{BinaryTemp[0]}{BinaryTemp[1]}{BinaryTemp[2]}{BinaryTemp[3]}";
            return Convert.ToInt32(bit0123, 2);
        }
        /// <summary>
        /// 获取bit0123
        /// </summary>
        /// <param name="a33">16进制80500033值</param>
        /// <returns>转bit0123</returns>
        public static int MIPI_serial_clk_dividerConfigValue(string a33) {
            int temp = Convert.ToInt32(a33, 16);
            var BinaryTemp = Convert.ToString(temp, 2).PadLeft(8, '0').ToList();
            string bit0123 = $"{BinaryTemp[4]}{BinaryTemp[5]}{BinaryTemp[6]}{BinaryTemp[7]}";
            return Convert.ToInt32(bit0123, 2);
        }
        /// <summary>
        /// 获取bit4567
        /// </summary>
        /// <param name="a33">16进制80500033值</param>
        /// <returns></returns>
        public static int MIPI_parallel_clk_dividerConfigValue(string a33) {
            int temp = Convert.ToInt32(a33, 16);
            var BinaryTemp = Convert.ToString(temp, 2).PadLeft(8, '0').ToList();
            string bit4567 = $"{BinaryTemp[0]}{BinaryTemp[1]}{BinaryTemp[2]}{BinaryTemp[3]}";
            return Convert.ToInt32(bit4567, 2);
        }
        /// <summary>
        /// 获取bit2
        /// </summary>
        /// <param name="a21">16进制80500021值</param>
        /// <returns>转bit2</returns>
        public static int system_clock_source_selectConfigValue(string a21) {
            int temp = Convert.ToInt32(a21, 16);
            var BinaryTemp = Convert.ToString(temp, 2).PadLeft(8, '0').ToList();
            return int.Parse(BinaryTemp[5].ToString());
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="a31">16进制80500021值</param>
        /// <returns>转bit2</returns>
        public static int arm_clock_source_selectConfigValue(string a31) {
            int temp = Convert.ToInt32(a31, 16);
            var BinaryTemp = Convert.ToString(temp, 2).PadLeft(8, '0').ToList();
            return int.Parse(BinaryTemp[5].ToString());
        }

        /// <summary>
        /// 获取bit01
        /// </summary>
        /// <param name="a21">16进制80500021值</param>
        /// <returns>转bit01</returns>
        public static int system_clock_divider_selectConfigValue(string a21) {
            int temp = Convert.ToInt32(a21, 16);
            var BinaryTemp = Convert.ToString(temp, 2).PadLeft(8, '0').ToList();
            string bit01 = $"{BinaryTemp[6]}{BinaryTemp[7]}";
            return Convert.ToInt32(bit01, 2);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="a31">16进制0x80500031</param>
        /// <returns></returns>

        public static int arm_clock_divider_selectConfigValue(string a31) {
            int temp = Convert.ToInt32(a31, 16);
            var BinaryTemp = Convert.ToString(temp, 2).PadLeft(8, '0').ToList();
            string bit01 = $"{BinaryTemp[6]}{BinaryTemp[7]}";
            return Convert.ToInt32(bit01, 2);
        }
        /// <summary>
        /// 获取bit01234567
        /// </summary>
        /// <param name="a20">16进制80500020值</param>
        /// <returns>转bit01234567</returns>
        public static int system_clock_dividerConfigValue(string a20) {
            int temp = Convert.ToInt32(a20, 16);
            //var BinaryTemp = Convert.ToString(temp, 2).PadLeft(8, '0').ToList();
            //string bit01234567 = $"{BinaryTemp[6]}{BinaryTemp[7]}{BinaryTemp[]}";
            return temp;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="a30">16进制0x8050030值</param>
        /// <returns></returns>
        public static int arm_clock_dividerConfigValue(string a30) {
            int temp = Convert.ToInt32(a30, 16);
            //var BinaryTemp = Convert.ToString(temp, 2).PadLeft(8, '0').ToList();
            //string bit01234567 = $"{BinaryTemp[6]}{BinaryTemp[7]}{BinaryTemp[]}";
            return temp;
        }

        /// <summary>
        /// 计算J11 判断是否为0等于1 否则等于
        /// </summary>
        /// <param name="a32">16进制80500032值</param>
        /// <returns></returns>
        public static double vco_loop_divfConfigFreq(string a32) {
            int pcdNum = vco_loop_divfConfigValue(a32);
            if (pcdNum == 0)
            {
                return 1;
            }
            else {
                return Math.Pow(2.0, pcdNum - 1.0);
            }
        }
        /// <summary>
        /// 计算J8
        /// </summary>
        /// <param name="a30">16进制80500030值</param>
        /// <returns></returns>
        public static double VCO_pre_dividerConfigFreq(string a30) {
            var padclkNum = double.Parse(jzTemp);
            var a2 = VCO_pre_dividerConfigValue(a30);
            return padclkNum/(1+a2);
        }
        /// <summary>
        /// 计算J9
        /// </summary>
        /// <param name="a30">16进制80500030值</param>
        /// <param name="a32">16进制80500032值</param> 
        /// <param name="a31">16进制80500031值</param>
        /// <returns></returns>
        public static double vco_loop_dividerConfigFreq(string a30,string  a32,string a31) {

            var b6 = VCO_pre_dividerConfigFreq(a30);
            var b2 = vco_loop_divfConfigFreq(a32);
            var a3 = vco_loop_dividerConfigValue(a31);
            return b6*(129-a3)*b2;
        }
        /// <summary>
        /// 计算b1
        /// </summary>
        /// <param name="a30">16进制80500030值</param>
        /// <param name="a32">16进制80500032值</param>
        /// <param name="a31">16进制80500031值</param>
        /// <returns></returns>
        public static double pll_clock_dividerConfigFreq(string a30, string a32, string a31) {
            var a1 = BypassPLLcoreConfigValue(a30);
            if (a1 == 1)
            {
                var padclkNum = int.Parse(jzTemp);
                return padclkNum;
            }
            else {
                var b7 = vco_loop_dividerConfigFreq(a30, a32, a31);
                var a5 = pll_clock_divider(a32);
                return b7 / (1 + a5);
            }
        }
        /// <summary>
        /// 计算b3
        /// </summary>
        /// <param name="a30">16进制80500030值</param>
        /// <param name="a33">16进制80500033值</param>
        /// <param name="a32">16进制80500032值</param>
        /// <param name="a31">16进制80500031值</param>
        /// <returns></returns>
        public static double MIPI_parallel_clk_dividerConfigFreq(string a30, string a33, string a32, string a31) {
            var a1 = BypassPLLcoreConfigValue(a30);
            if (a1 == 1)
            {
                var padclkNum = int.Parse(jzTemp);
                return padclkNum;
            }
            else {
                var b7 = vco_loop_dividerConfigFreq(a30, a32, a31);
                var a6 = MIPI_serial_clk_dividerConfigValue(a33);
                var a7 = MIPI_parallel_clk_dividerConfigValue(a33);
                return b7 / (1 + a6) / (1 + a7);
            }
        }
        /// <summary>
        /// 计算b5
        /// </summary>
        /// <param name="a21"></param>
        /// <param name="a30"></param>
        /// <param name="a32"></param>
        /// <returns></returns>
        public static double system_clock_divider_selectConfigFreq(string a21, string a30, string a32,string a33,string a31) {
            var a9 = system_clock_divider_selectConfigValue(a21);
            var b3 = MIPI_parallel_clk_dividerConfigFreq(a30, a33, a32, a31);
            var b1 = pll_clock_dividerConfigFreq(a30, a32, a31);
            if (a9 > 1)
            {
                return b3;
            }
            else {
                if (a9 == 0)
                {
                    var padclkNum = int.Parse(jzTemp);
                    return padclkNum;
                }
                else {
                    return b1;
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="a21">0x80500031</param>
        /// <param name="a30"></param>
        /// <param name="a32"></param>
        /// <param name="a33"></param>
        /// <param name="a31"></param>
        /// <returns></returns>
        public static double arm_clock_divider_selectConfigFreq(string a21, string a30, string a32, string a33, string a31) {

            var a9 = arm_clock_divider_selectConfigValue(a21);
            var b3 = MIPI_parallel_clk_dividerConfigFreq(a30, a33, a32, a31);
            var b1 = pll_clock_dividerConfigFreq(a30, a32, a31);
            if (a9 > 1)
            {
                return b3;
            }
            else
            {
                if (a9==0)
                {
                    var padclkNum = int.Parse(jzTemp);
                    return padclkNum;
                }
                else
                {
                    return b1;
                }
            }
            return 0;
        }
        /// <summary>
        /// 计算b4
        /// </summary>
        /// <param name="a20"></param>
        /// <param name="a21"></param>
        /// <param name="a30"></param>
        /// <param name="a31"></param>
        /// <param name="a32"></param>
        /// <param name="a33"></param>
        /// <returns></returns>
        public static double system_clock_dividerConfigFreq(string a20, string a21, string a30, string a31, string a32, string a33) {
            var b5 = system_clock_divider_selectConfigFreq(a21, a30, a32, a33, a31);
            var a8 = system_clock_dividerConfigValue(a20);
            return b5 / (a8 == 0 ? 1 : a8);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="a20">0x8050030</param>
        /// <param name="a21">0x80500031</param>
        /// <param name="a30"></param>
        /// <param name="a31"></param>
        /// <param name="a32"></param>
        /// <param name="a33"></param>
        /// <returns></returns>
        public static double arm_clock_dividerConfigFreq(string a20, string a21, string a30, string a31, string a32, string a33) {

            var b5 = arm_clock_divider_selectConfigFreq(a21, a30, a32, a33, a31);
            var a8 = arm_clock_dividerConfigValue(a20);
            return b5 / (a8 == 0 ? 1 : a8);
        }

        /// <summary>
        /// 计算系统频率
        /// </summary>
        /// <param name="a20"></param>
        /// <param name="a21"></param>
        /// <param name="a30"></param>
        /// <param name="a31"></param>
        /// <param name="a32"></param>
        /// <param name="a33"></param>
        /// <returns></returns>
        public static double sys_clk(string a20, string a21, string a30, string a31, string a32, string a33) {

            var a10 = system_clock_source_selectConfigValue(a21);
            var b4 = system_clock_dividerConfigFreq(a20, a21, a30, a31, a32, a33);
            if (a10 == 1)
            {
                return b4;
            }
            else {
                var padclkNum = int.Parse(jzTemp);
                return padclkNum;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="a20">0x8050030</param>
        /// <param name="a21">0x80500031</param>
        /// <param name="a30"></param>
        /// <param name="a31"></param>
        /// <param name="a32"></param>
        /// <param name="a33"></param>
        /// <returns></returns>
        public static double arm_clk(string a20, string a21, string a30, string a31, string a32, string a33) {
            var e52 = arm_clock_source_selectConfigValue(a21);
            var b4 = arm_clock_dividerConfigFreq(a20, a21, a30, a31, a32, a33);
            if (e52 == 1)
            {
                return b4;
            }
            else
            {
                var padclkNum = int.Parse(jzTemp);
                return padclkNum;
            }
            
        }
    }
}
